# Gstreamer Player file for Lsongs
#  @author Georgi Damyanov 
#
# This work is released under the GNU GPL, version 2 or later.
#
# TODO:
# Clean up useless variables
# Add CD and Streams Support
# Add fadein fadeout support

import sys
import time,re
import pygst
pygst.require('0.10')
import gst
from gst import *
from qt import QObject,QThread,QCustomEvent,QApplication,QEvent

NO_FADE=0
FADE_IN=1
FADE_OUT=2
CROSSFADE=3

def cleanPath(filePath):
	return re.sub(r"#",r"%23",filePath)
	
class GSTEngine(QObject):
	def __init__(self):
		#QThread.__init__(self)	
		self.fade=CROSSFADE
		#self.bin=element_factory_make('thread','thread0')
		self.bin=gst.Pipeline('pipeline')
		self.file=element_factory_make('filesrc','source')
		#self.decoder=element_factory_make('spider','spider0')
		self.decoder=element_factory_make('mad','MAD')
		##GTD:: Eq not working yet
		##self.eq=element_factory_make('equalizer','eq')
		self.audioConverter=element_factory_make('audioconvert','ac')
		self.volumeControl=element_factory_make('volume','volume0')
		self.audioSink=element_factory_make('autoaudiosink','sink')
		#self.audioSink=element_factory_make('artsdsink','sink')
		self.currentPosition=0
		self.currentTime=0
		self.TotalTime=100
		self.track=None
		#add to GstPipeline
		for e in (self.file,self.decoder,self.volumeControl,self.audioSink, self.audioConverter):
			print e
			self.bin.add(e)
		#link GstElements
		self.file.link(self.decoder)
		self.decoder.link(self.audioConverter)
		self.audioConverter.link(self.volumeControl)
		self.volumeControl.link(self.audioSink)
		self.paused=False
		#self.decoder.connect('eos',self.eos)
		
	
	def run(self,track):	self.play(track)
	def stop(self):	self.playPause()
	def play(self,track):
		self.bin.set_state(STATE_READY)
		#self.endofstream=False
		#FIXME -ugly fix to create status display
		#time.sleep(0.15) 
		self.track=track
		self.file.set_property('location',track.location)
		#self.file.set_property('location',track)#.location)
		print self.bin.set_state(STATE_PLAYING),'set state playing'
		self.paused=False

	def playPause(self):
		if self.isPaused: 
			self.bin.set_state(STATE_PLAYING)
			self.paused=False
		else: self.pause()
			
	def pause(self): 
		self.bin.set_state(STATE_PAUSED)
		self.paused=True

	def ready(self): self.bin.set_state(STATE_READY)

	def stop(self): print self.bin.set_state(STATE_NULL),'set state NULL'
	
	def isPlaying(self): return (self.bin.get_state()[1]==STATE_PLAYING)
	def getState(self): return (self.bin.get_state())#,self.audioSink.get_state(),self.file.get_state())
	def setStateNull(self): 
		self.bin.set_state(STATE_READY)
		self.bin.set_state(STATE_NULL)
		
	def isPaused(self): return (self.bin.get_state()[1]==STATE_PAUSED)
		
	def isReady(self): 
		#print ">>",self.bin.get_state()[1],"<<"
		return self.bin.get_state()[1]==STATE_READY

	def forcedPause(self): return self.paused
	#GTD:: eos signal crashes the entire application	
	#GSTPlayer uses a workaround
	'''
	def eos(self): 
		print "EMITED SIGNAL"
		self.endofstream=True
		self.bin.set_state(STATE_NULL)
	'''
	def isEOS(self): return False #self.endofstream
	def getBus(self): return self.bin.get_bus() #self.endofstream
	
	def getPosition(self):
		self.currentTime,format=self.decoder.query_position(gst.FORMAT_TIME)
		self.TotalTime,format=self.decoder.query_duration(gst.FORMAT_TIME)
		return (self.currentTime/1000000.0,self.TotalTime/1000000.0)
		
	def setPos(self,time):
		return self.audioSink.seek(1.0, gst.FORMAT_TIME,
            gst.SEEK_FLAG_FLUSH | gst.SEEK_FLAG_ACCURATE,
            gst.SEEK_TYPE_SET, long(time*1000000.0),
            gst.SEEK_TYPE_NONE, 0)
	
	def getVolume(self):
		return self.volumeControl.get_property('volume')
	
	def setVolume(self,volume):
		self.volumeControl.set_property('volume',float(volume/100.0))
	
	def __del__(self):
		time.sleep(0.2)
		print self.bin.set_state(STATE_NULL),'STATE_NULL'
		time.sleep(0.2)
		print "GST object destroyed"
	
	def setEQ(self,eq):
		pass
		"""	
		if(eq['On']):
			self.eq.set_property('active',True)
			gains=[]
			self.eq.set_property('preamp',eq['preamp'])
			for i in xrange(0,10):
				gains[i]=10*eq['Bands'][i]
			self.eq.set_property('gain',gains)
		else: self.eq.set_property('active',False)
		"""
		
	
	#TODO fade in/fade out function implemented here
	def FadeTimer():
		pass
		
if __name__ == '__main__':
	l=GSTEngine()
	print 'about to play'
	#time.sleep(2)
	l.play('/home/phr/test.mp3')
	print 'after play'
	time.sleep(2)
	print l.setVolume(100)
	time.sleep(2)
	print l.getVolume()
	while 1:#l.bin.iterate():
		print l.getPosition()
		time.sleep(1)
		print l.isReady(),'    ',l.isPlaying()
		if l.isPaused(): 
			print 'calling playpause'
			l.playPause()	
	print l.isReady(),'    ',l.isPlaying()
	time.sleep(5)
	print l.isReady(),'    ',l.isPlaying()
	print 'done'
	
	
